using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using MSOutlook = Microsoft.Office.Interop.Outlook;
using Utility = Microsoft.Sample.Outlook.Utility;

namespace Microsoft.Sample.Outlook.CRMIntegration.ItemForms
{
    internal sealed partial class OpportunityForm : Form
	{
		Utility.ItemAdapter _opportunity;

		public OpportunityForm()
		{
			InitializeComponent();
		}

		public OpportunityForm(Utility.ItemAdapter item)
		{
			InitializeComponent();

			if (item.Class != MSOutlook.OlObjectClass.olPost)
				throw new ApplicationException("ActivityForm can only be initalized with outlook post items");

			_opportunity = item;
		}

		public void CopyDataFromItem(Utility.ItemAdapter item)
		{
			if (item == null)
				return;

			if (item.Class == MSOutlook.OlObjectClass.olMail)
			{
				MSOutlook.MailItem mail = item.GetAsMail();

				this.textBoxComments.Text = mail.Body;
				this.textBoxName.Text = mail.Subject;
				this.comboBoxSalesStage.Text = "Prospect 0%";
			}

			if (item.Class == MSOutlook.OlObjectClass.olAppointment)
			{
				MSOutlook.AppointmentItem appt = item.GetAsAppointment();

				this.textBoxComments.Text = appt.Body;
				this.textBoxName.Text = appt.Subject;
				this.comboBoxSalesStage.Text = "Prospect 0%";
			}
		}


		private void OpportunityForm_Load(object sender, EventArgs e)
		{
			this.accountsTableAdapter.Fill(this.crmDataSet.Accounts);

			if (_opportunity == null)
			{
				opportunitiesBindingSource.AddNew();
				CurrentRow.LocalID = Guid.NewGuid();

				comboBoxAccount.Enabled = true;
			}
			else if (_opportunity.EntryID == null)
			{
				opportunitiesBindingSource.AddNew();
				CurrentRow.LocalID = Guid.NewGuid();

				comboBoxAccount.SelectedValue = AccountFolderID.Value;
			}
			else
			{
				this.opportunitiesTableAdapter.FillByOutlookID(this.crmDataSet.Opportunities, _opportunity.EntryID);
			}

		}

		private Guid? AccountFolderID
		{
			get
			{
				if (_opportunity == null)
					return null;

				MSOutlook.MAPIFolder folder = (MSOutlook.MAPIFolder)_opportunity.Parent;
				MSOutlook.MAPIFolder accountFolder = (MSOutlook.MAPIFolder)folder.Parent;

				CrmDataSetTableAdapters.AccountsTableAdapter accountsAdapter = new CrmDataSetTableAdapters.AccountsTableAdapter();
				return (Guid)accountsAdapter.GetLocalID(accountFolder.EntryID);
			}
		}

		private CrmDataSet.OpportunitiesRow CurrentRow
		{
			get
			{
				DataRowView view = (DataRowView)opportunitiesBindingSource.Current;
				return (CrmDataSet.OpportunitiesRow)view.Row;
			}
		}


		private void btnSaveClose_Click(object sender, EventArgs e)
		{
            if (ValidateChildren() == false)
                return;

			opportunitiesBindingSource.EndEdit();

			CrmDataSet.OpportunitiesRow row = this.CurrentRow;

			if (_opportunity == null)
			{
				string entryID = (string)accountsTableAdapter.GetOutlookID(row.AccountID);
				MSOutlook.MAPIFolder accountfolder = Globals.ThisApplication.Application.Session.GetFolderFromID(
					entryID, Globals.ThisApplication.Application.ActiveExplorer().CurrentFolder.StoreID);

				MSOutlook.MAPIFolder folder = Utility.Folder.GetFolder(accountfolder, Properties.Resources.OpportunitiesFolderName);
				_opportunity = Utility.ItemAdapter.FromObject(folder.Items.Add(MSOutlook.OlItemType.olPostItem));
			}

			if (Utility.SyncEngine.SyncItem<CrmDataSet.OpportunitiesRow>(row, _opportunity, Utility.SyncDirection.ItemToOutlook))
				_opportunity.Save();

			if (CurrentRow.OutlookID != _opportunity.EntryID)
				CurrentRow.OutlookID = _opportunity.EntryID;

			int i = this.opportunitiesTableAdapter.Update(this.crmDataSet.Opportunities);
			if (associations != null)
				associations.Save();

			this.Close();

		}

		OpportunityAssoicationsControl associations = null;

		private void btnAssociations_Click(object sender, EventArgs e)
		{
			if (associations != null)
				return;

            Guid? accountID = AccountFolderID;
            if (accountID.HasValue == false)
            {
                if (comboBoxAccount.SelectedValue != null)
                    accountID = (Guid)comboBoxAccount.SelectedValue;
            }
            associations = new OpportunityAssoicationsControl(accountID, CurrentRow.LocalID);
			associations.Dock = DockStyle.Right;

			panelAssociations.Width = associations.Width;
			this.Width += associations.Width;
			panelAssociations.Controls.Add(associations);

            btnAssociations.Enabled = false;
		}

		private void comboBoxAccount_SelectedValueChanged(object sender, EventArgs e)
		{
			if (associations != null)
				associations.ChangeAccount((Guid)comboBoxAccount.SelectedValue);
		}

        private void textBoxName_Validating(object sender, CancelEventArgs e)
        {
            if (textBoxName.Text.Length > 0)
            {
                errorProvider.SetError(textBoxName, "");
                return;
            }

            errorProvider.SetError(textBoxName, "An Opportunity must have a name");
            e.Cancel = true;

        }

        private void comboBoxAccount_Validating(object sender, CancelEventArgs e)
        {
            if (comboBoxAccount.SelectedValue != null)
            {
                errorProvider.SetError(comboBoxAccount, "");
                return;
            }

            errorProvider.SetError(comboBoxAccount, "An account must be selected");
            e.Cancel = true;
        }

        private void comboBoxSalesStage_Validating(object sender, CancelEventArgs e)
        {
            if (comboBoxSalesStage.SelectedItem != null)
            {
                errorProvider.SetError(comboBoxSalesStage, "");
                return;
            }

            errorProvider.SetError(comboBoxSalesStage, "An opportunity must have a selected sales stage");
            e.Cancel = true;
        }

        private void textBoxSize_Validating(object sender, CancelEventArgs e)
        {
            decimal size;
            if (decimal.TryParse(textBoxSize.Text, out size) || string.IsNullOrEmpty(textBoxSize.Text))
            {
                errorProvider.SetError(textBoxSize, "");
                return;
            }

            errorProvider.SetError(textBoxSize, "An opportunity size must be a decimal number");
            e.Cancel = true;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Dispose();
        }
	}
}